home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * All mallocs from irit modules should be piped through this allocator. *
- * *
- * Written by Gershon Elber, April 1933 *
- ******************************************************************************/
-
- #include <stdio.h>
-
- #include <string.h>
- #include "irit_sm.h"
- #include "imalloc.h"
-
- #define OVERWRITE_STAMP_START 1234567890L /* A long */
- #define OVERWRITE_STAMP_END 0xbd /* A byte */
- #define OVERWRITE_STAMP_FREED -50964L /* A long */
- #define FREE_TABLE_SIZE 100000
-
- #if defined(AMIGA) && defined(__SASC)
- static VoidPtr __far AllocPtrTable[FREE_TABLE_SIZE];
- #else
- static VoidPtr AllocPtrTable[FREE_TABLE_SIZE];
- #endif
- static long
- IritDebugSearchPtr = 0;
- static int
- AllocNumPtrs = 0,
- IritDebugMalloc = FALSE,
- IritDebugMallocTested = FALSE;
-
- static void AllocError(char *Msg, VoidPtr *p);
-
- /*****************************************************************************
- * My Routine to allocate dynamic memory. All program requests must call this *
- * routine (no direct call to malloc). *
- *****************************************************************************/
- static void AllocError(char *Msg, VoidPtr *p)
- {
- char s[128];
-
- sprintf(s, "%s, Ptr = 0x%lx", Msg, (unsigned long) p);
-
- fprintf(stderr, "Memory allocation error, %s\n", s);
- }
-
- /*****************************************************************************
- * Free all allocated object to test for overwritten data. *
- *****************************************************************************/
- void IritTestAllDynMemory(int PrintAlloc)
- {
- int i;
-
- for (i = 0; i < AllocNumPtrs; i++) {
- if (AllocPtrTable[i] != NULL) {
- unsigned long
- size = *((unsigned long *) AllocPtrTable[i]);
- VoidPtr
- p2 = ((char *) AllocPtrTable[i]) + 8 + size;
-
- if (*((long *) ((char *) AllocPtrTable[i] + 4)) !=
- OVERWRITE_STAMP_START)
- AllocError("Overwritten start of dynamically allocated memory",
- AllocPtrTable[i]);
- else if (*((unsigned char *) p2) != OVERWRITE_STAMP_END)
- AllocError("Overwritten end of dynamically allocated memory",
- AllocPtrTable[i]);
-
- if (PrintAlloc)
- printf("Allocated 0x%08lx\n", AllocPtrTable[i]);
- }
- }
- }
-
- /*****************************************************************************
- * My Routine to allocate dynamic memory. All program requests must call this *
- * routine (no direct call to malloc). Dies if no memory. *
- *****************************************************************************/
- VoidPtr IritMalloc(unsigned size)
- {
- VoidPtr p;
- unsigned OldSize;
-
- if (!IritDebugMallocTested) {
- IritDebugMalloc = getenv("IRIT_MALLOC") != NULL;
- IritDebugSearchPtr = getenv("IRIT_MALLOC_PTR") != NULL ?
- atoi(getenv("IRIT_MALLOC_PTR")) : 0;
- IritDebugMallocTested = TRUE;
- }
-
- if (IritDebugMalloc) {
- IritTestAllDynMemory(0);
-
- OldSize = size;
- size += 16;
- }
-
- if ((p = malloc(size)) != NULL) {
- if (IritDebugMalloc) {
- int i;
- VoidPtr p2;
-
- if (p != NULL && ((long) p) == IritDebugSearchPtr) {
- printf("Pointer 0x%08lx just allocated\n", p);
- }
-
- /* Save allocated pointer so we can search for it when freed. */
- for (i = 0; i < AllocNumPtrs; i++) {
- if (AllocPtrTable[i] == NULL) {
- AllocPtrTable[i] = p;
- break;
- }
- }
-
- if (i >= AllocNumPtrs) {
- if (i < FREE_TABLE_SIZE - 1)
- AllocPtrTable[AllocNumPtrs++] = p;
- else {
- fprintf(stderr, "Allocation table too small.\n");
- exit(1);
- }
- }
-
- *((long *) p) = OldSize;
- *((long *) (((char *) p) + 4)) = OVERWRITE_STAMP_START;
- p = ((char *) p) + 8;
- p2 = ((char *) p) + OldSize;
- *((char *) p2) = (char) OVERWRITE_STAMP_END;
-
- *((char *) p) = 0; /* In case the freed stamp is still there. */
- }
-
- return p;
- }
-
- IritFatalError("Not Enough dynamic memory");
-
- return NULL; /* Make warnings silent. */
- }
-
- /*****************************************************************************
- * My Routine to free dynamic memory. All program requests must call this *
- * routine (no direct call to free). *
- *****************************************************************************/
- void IritFree(VoidPtr p)
- {
- if (IritDebugMalloc) {
- int i;
-
- if (*((long *) p) == OVERWRITE_STAMP_FREED)
- AllocError("Trying to free a free object again", p);
-
- if (p == NULL)
- AllocError("Free a NULL pointer", p);
-
- IritTestAllDynMemory(0);
-
- *((long *) p) = OVERWRITE_STAMP_FREED;
- p = ((char *) p) - 8;
-
- /* Compare the freed pointer with the list of allocated ones. */
- for (i = 0; i < AllocNumPtrs; i++) {
- if (AllocPtrTable[i] == p) {
- AllocPtrTable[i] = NULL;
- break;
- }
- }
-
- if (i >= AllocNumPtrs)
- AllocError("Free unallocated pointer", p);
- }
-
- #ifdef __DEBUG_TC_MALLOC__
- switch (heapcheck()) {
- case _HEAPCORRUPT:
- AllocError("Heap is corrupted", p);
- break;
- case _BADNODE:
- AllocError("Attempt to free a bogus pointer", p);
- break;
- case _FREEENTRY:
- AllocError("Attempt to free an already freed pointer", p);
- break;
- case _HEAPOK:
- case _HEAPEMPTY:
- case _USEDENTRY:
- break;
- default:
- AllocError("Allocation error", p);
- break;
-
- }
- #endif /* __DEBUG_TC_MALLOC__ */
-
- free(p);
- }
-